// Copyright (c) 2005  INRIA Sophia-Antipolis (France).
// All rights reserved.
//
// This file is part of cgal-python; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public License as
// published by the Free Software Foundation; version 2.1 of the License.
// See the file LICENSE.LGPL distributed with cgal-python.
//
// Licensees holding a valid commercial license may use this file in
// accordance with the commercial license agreement provided with the software.
//
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
//
// $Id: Py_Ray_2.cpp 167 2007-11-02 15:36:54Z spion $
// $URL: svn+ssh://scm.gforge.inria.fr/svn/cgal-python/trunk/cgal-python/bindings/Kernel/Py_Ray_2.cpp $
//
// Author(s)     : Naceur Meskini
//=========================================================================

#include <CGAL/basic.h>
#include <include/Kernels.h>

#include <boost/python.hpp>
#include <boost/cstdint.hpp>

const char* Ray_2_doc[]=
{
"An object r of the data type Ray_2 is a directed straight ray in the two-dimensional Euclidean plane ExE. It starts in a point called the source of r and goes to infinity.\n"\
"for more details see a C++ doc:\n\
http://www.cgal.org/Manual/3.2/doc_html/cgal_manual/Kernel_23_ref/Class_Ray_2.html",
"r = Ray_2(self,Point_2 p,Point_2 q)\nintroduces a ray with source p and passing through point q.\n"\
"r = Ray_2(self,Point_2 p,Direction_2 d)\nintroduces a ray starting at source p with direction d.\n"\
"r = Ray_2(self,Point_2 p,Vector_2 v)\nintroduces a ray r starting at source p with the direction of v.\n"\
"r = Ray_2(self,Point_2 p,line_2 l)\nintroduces a ray r starting at source p with the same direction as l.\n",
"source(self) -> Point_2\nreturns the source of r\n",
"point(self,i) -> Point_2\nreturns a point on r. point(0) is the source, point(i), with i>0, is different from the source.\nPrecondition: i 0.\n",
"is_degenerate(self) -> bool\nray r is degenerate, if the source and the second defining point fall together (that is if the direction is degenerate).\n",
"direction(self) -> Direction_2\nreturns the direction of r.\n",
"to_vector(self) -> Vector_2\nreturns a vector giving the direction of r\n",
"has_on(self,Point_2 p) -> bool\nA point is on r, iff it is equal to the source of r, or if it is in the interior of r\n",
"collinear_has_on(self,Point_2 p) -> bool\nchecks if point p is on r.\nThis function is faster than function has_on() if the precondition checking is disabled.\nPrecondition: p is on the supporting line of r.\n",
"opposite(self) -> Ray_2\nreturns the ray with the same source and the opposite direction.\n",
"supporting_line(self) -> line_2\nreturns the line supporting r which has the same direction.\n",
"transform(Aff_transformation_2 t) -> Ray_2\nreturns the ray obtained by applying t on the source and on the direction of r.\n"
};

template<class Ray_2>
boost::python::str py_repr_Ray_2(const Ray_2& r )
{
	using namespace boost::python;
	return str("Ray_2("+ str(r.source()) +","+ str(r.direction()) +")" );
}

template<class kernel>
void Py_Ray_2()
{
	typedef typename kernel::Point_2 					Point_2;
	typedef typename kernel::Segment_2 					Segment_2;
 	typedef typename kernel::Vector_2 					Vector_2;
 	typedef typename kernel::Direction_2 					Direction_2;
 	typedef typename kernel::Line_2 					Line_2;
  	typedef typename kernel::Ray_2 					        Ray_2;
 	typedef typename kernel::Triangle_2 					Triangle_2;
	typedef typename kernel::Iso_rectangle_2 				Iso_rectangle_2;
	typedef typename kernel::Circle_2 				      	Circle_2;
	typedef typename kernel::Aff_transformation_2 				Aff_transformation_2;
	typedef typename kernel::FT 						FT;
	typedef typename kernel::RT						RT;

	using namespace boost::python;

        class_< Ray_2 >("Ray_2", Ray_2_doc[0], init<>())
        .def(init< const Ray_2& >(Ray_2_doc[1]))
        .def(init< const Point_2&, const Point_2& >())
        .def(init< const Point_2&, const Direction_2& >())
        .def(init< const Point_2&, const Vector_2& >())
        .def(init< const Point_2&, const Line_2& >())
#if CGAL_VERSION_NR < 1030301000
        .def("source", &Ray_2::source, by_cref(), Ray_2_doc[2])
        .def("second_point", &Ray_2::second_point, by_cref())
#else
        .def("source", &Ray_2::source, typename Value_or_cref<typename kernel::Construct_source_2, Ray_2 > ::type(), Ray_2_doc[2])
        .def("second_point", &Ray_2::second_point, typename Value_or_cref<typename kernel::Construct_second_point_2, Ray_2 > ::type())
#endif
        .def("point", &Ray_2::point, Ray_2_doc[3])
#if CGAL_VERSION_NR < 1030301000
        .def("start", &Ray_2::start, by_cref())
#else
        .def("start", &Ray_2::start, typename Value_or_cref<typename kernel::Construct_source_2, Ray_2 > ::type())
#endif
        .def("is_horizontal", &Ray_2::is_horizontal)
        .def("is_vertical", &Ray_2::is_vertical)
        .def("is_degenerate", &Ray_2::is_degenerate, Ray_2_doc[4])
        .def("direction", &Ray_2::direction, Ray_2_doc[5])
        .def("to_vector", &Ray_2::to_vector, Ray_2_doc[6])
        .def("has_on", &Ray_2::has_on, Ray_2_doc[7])
        .def("collinear_has_on", &Ray_2::collinear_has_on, Ray_2_doc[8])
        .def("opposite", &Ray_2::opposite, Ray_2_doc[9])
        .def("supporting_line", &Ray_2::supporting_line, Ray_2_doc[10])
        .def("transform", &Ray_2::transform, Ray_2_doc[11])
 	.def("__repr__", &py_repr_Ray_2<Ray_2>)
        .def( self == self )
        .def( self != self )
    ;
}

void export_Ray_2()
{
	Py_Ray_2<K>();
}
